#include "Thread.hpp"
#include "BlockQueue.hpp"
#include "Task.hpp"
#include <ctime>

using namespace yss;

void ProductorCore(BlockQueue<Task> &bq)
{
    srand(time(nullptr));
    while(true)
    {
        sleep(1);
        int a = rand() % 10 + 1;
        usleep(1000);
        int b = rand() % 20 + 1;
        Task t(a, b);
        bq.Enqueue(t);
        cout << "Productor: " << t.DToString() << endl;
    }
}
void ConsumerCore(BlockQueue<Task> &bq)
{
    while(true)
    {
        Task t;
        bq.Pop(t);
        t.Excute();
        cout << "Consumer: " << t.RToString() << endl;
    }
}

void SatrtComm(vector<Thread<BlockQueue<Task>>> *threads, int num, BlockQueue<Task> &bq, func_t<BlockQueue<Task>> func)
{
    for(int i=0; i<num; i++)
    {
        string name = "thread-" + to_string(i+1);
        threads->emplace_back(func, bq, name);
        threads->back().Start();
    }
}

void StartProductor(vector<Thread<BlockQueue<Task>>> *threads, int num, BlockQueue<Task> &bq)
{
    SatrtComm(threads, num, bq, ProductorCore);
}
void StartConsumer(vector<Thread<BlockQueue<Task>>> *threads, int num, BlockQueue<Task> &bq)
{
    SatrtComm(threads, num, bq, ConsumerCore);
}

void WaitAll(vector<Thread<BlockQueue<Task>>> &threads)
{
    for(auto &t : threads)
    {
        t.Join();
    }
}

int main()
{
    BlockQueue<Task> *bq = new BlockQueue<Task>(5);
    vector<Thread<BlockQueue<Task>>> threads;
    StartProductor(&threads, 1, *bq);
    StartConsumer(&threads, 1, *bq);
    WaitAll(threads);//
    return 0;
}